<template>
  <el-dialog v-model="drawer" @close="close" :append-to-body="true" width="660px" title="表头设置">
    <el-form :model="form" :rules="rules" label-width="0" class="drawer-form" ref="ruleFormRef">
        <el-table :data="form.header" size="small" border ref="headerTable" @select-all="selectEvent" @select="selectEvent">
            <el-table-column type="selection" width="30" fixed="left"></el-table-column>
            <el-table-column prop="name" label="表头名" width="208px">
                <template #default="scope">
                    <span style="width:130px;display:inline-block;font-size:12px;">{{scope.row.name}}</span>
                </template>
            </el-table-column>
            <el-table-column prop="remark" label="备注">
                <template #default="scope">
                    <span style="font-size:12px;">{{scope.row.remark}}</span>
                </template>
            </el-table-column>
        </el-table>
    </el-form>
    <el-row class="footer-fixed">
        <el-button type="primary" :loading="submitLoading" size="small" @click="submit(ruleFormRef)">保存</el-button>
        <el-button size="small" @click="cancel(ruleFormRef)">取消</el-button>
    </el-row>
  </el-dialog>
</template>
<script>
import {computed, reactive, toRefs, watch, ref, nextTick, onUpdated, onBeforeMount} from 'vue'
import { EditPen, Check } from '@element-plus/icons-vue'
import Sortable from 'sortablejs'
import {customerTableHeaderCache} from "/@/stores/ums/customer/customerTableHeaderStores";
import {storeToRefs} from "pinia";


export default {
    name: 'TableHeader',
    props: {
        dialogDrawer: {
            type: Boolean,
            default: false
        },
        defaultHeader: {
            type: Array,
            default() {
                return []
            }
        }
    },
    setup(props, context) {
        const {list: tableHeaderList} = storeToRefs(customerTableHeaderCache())
        const { dialogDrawer, defaultHeader } = toRefs(props)
        const ruleFormRef = ref()
        const headerTable = ref()
        // 控制提交按钮显示加载状态
        const submitLoading = ref(false)
        // 当前选中的状态的 ids 列表
        const selectStatusIds = ref([])
        const state = reactive({
            form: {
                header: defaultHeader.value
            },
            rules: {},
            checkAll: false,
            isIndeterminate: false,
            checkedHeader: []
        })

        state.form.header = tableHeaderList

        // 加载列表
        // onBeforeMount(()=>{})

        // 在更新时将显示的表头设置为选中状态，隐藏的不选中状态
        onUpdated(()=>{
            // 清除状态，重新添加，保存一致性
            headerTable.value?.clearSelection()
            selectStatusIds.value = []
            state.form.header.forEach((row) => {
                // 检查状态：0显示，1不显示
                if (row['visible'] === 0){
                    headerTable.value?.toggleRowSelection(row, undefined)
                    // 初始状态添加到已选中状态
                    selectStatusIds.value.push(row.id)
                }
            })

        })
        // 当用户手动勾选数据行的 Checkbox 时触发的事件
        // 当用户手动勾选全选 Checkbox 时触发的事件
        const selectEvent = (e) => {
            // 针对选中的进行保存
            selectStatusIds.value = e.map(s => s.id)
        }
        // 双向绑定代理
        let drawer = computed({
            get: () => dialogDrawer.value,
            set: (val) => {
                context.emit('update:dialogDrawer', val)
            }
        })
        // 双向绑定代理
        let tableList = computed({
            get(){
                let arr = []
                for(let i = 0; i < defaultHeader.value.length; i ++) {
                    arr.push(defaultHeader.value[i])
                }
                return {
                    header: arr
                }
            },
            set(val) {
                context.emit('update:defaultForm', val)
            }
        })
        // 监听表头设置显示隐藏
        watch(() => dialogDrawer.value, val => {
            context.emit("update:dialogDrawer", val)
            if(val) {
                state.form.header.forEach((row) => {
                    headerTable.value?.toggleRowSelection(row, undefined)
                })
                nextTick(() => {
                    initSort()
                })
            }
        })
        // 关闭表头设置
        const close = () => {
            context.emit("update:dialogDrawer", false)
        }
        // 提交保存
        const submit = async (formEl) => {
            // 校验表单
            if (formEl) await formEl.validate(async (valid) => {
                if (!valid) return
                // 进行修改
                submitLoading.value = true
                await customerTableHeaderCache().batchVisibleByIds(selectStatusIds.value)
                submitLoading.value = false
                selectStatusIds.value = []
                context.emit('onSubmit', true)
                context.emit("update:dialogDrawer", false)
            })
        }
        const cancel = (formEl) => {
            if (!formEl) return
            formEl.resetFields()
            context.emit("update:dialogDrawer", false)
        }
        const editName = index => {
            state.form.header[index].edit = !state.form.header[index].edit
        }
        const editRemark = index => {
            state.form.header[index].editRemark = !state.form.header[index].editRemark
        }
        const initSort = () => {
            const tbody = document.querySelector('.drawer-form .el-table__body-wrapper tbody');
            Sortable.create(tbody, {
                animation: 180,
                delay: 0,
                onEnd({ newIndex, oldIndex }) {
                    const currRow = tableList.value.header.splice(oldIndex, 1)[0];
                    tableList.value.header.splice(newIndex, 0, currRow);
                },
            })
        }
        return {
            drawer,
            ...toRefs(state),
            close,
            ruleFormRef,
            submit,
            cancel,
            editName,
            EditPen,
            editRemark,
            Check,
            headerTable,
            tableList,
            selectEvent,
            submitLoading
        }
    }
}
</script>

<style scoped lang="scss">
.drawer-form{
    padding: 10px 10px 64px;
}
.footer-fixed{
    position: absolute;
    left: 0;
    bottom: 0;
    right: 0;
    padding: 10px;
    background: #fff;
    z-index: 999;
    display: flex;
    justify-content: center;
    box-shadow: rgba(0, 0, 0, 0.1) 0px 0px 5px 0px, rgba(0, 0, 0, 0.1) 0px 0px 1px 0px;
}
</style>
